import HttpRequest from './http'
import { merge } from 'lodash-es'
import { HttpRequestOptions, RequestHooks } from './type'
import { getToken } from '../auth'
import { RequestCodeEnum, RequestMethodsEnum } from '@/enums/requestEnums'
import { useUserStore } from '@/stores/user'
import { client } from '../client'
import router from '@/router'

const requestHooks: RequestHooks = {
    requestInterceptorsHook(options, config) {
        const { urlPrefix, baseUrl, withToken } = config
        options.header = options.header ?? {}
        
        // APP 平台下，在转换前记录商品详情接口的原始请求信息
        // #ifdef APP-PLUS
        const originalUrl = options.url
        const originalData = options.data
        const isGoodsDetail = originalUrl.includes('goods/detail') || originalUrl.includes('goodsDetail')
        // #endif
        
        // GET 请求时，将 data 转换为查询参数
        if (options.method?.toUpperCase() === RequestMethodsEnum.GET && options.data) {
            const queryString = Object.keys(options.data)
                .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(options.data[key])}`)
                .join('&')
            if (queryString) {
                options.url += (options.url.includes('?') ? '&' : '?') + queryString
            }
            // GET 请求不需要 data 字段
            delete options.data
        }
        
        if (urlPrefix) {
            options.url = `${urlPrefix}${options.url}`
        }
        if (baseUrl) {
            options.url = `${baseUrl}${options.url}`
        }
        
        // APP 平台下，记录商品详情接口的请求信息
        // #ifdef APP-PLUS
        if (isGoodsDetail) {
            console.log('APP 商品详情接口请求:', {
                originalUrl,
                finalUrl: options.url,
                method: options.method,
                originalData: originalData,
                hasId: !!originalData?.id,
                idValue: originalData?.id,
                hasToken: !!options.header['like-token']
            })
        }
        // #endif
        
        const token = getToken()
        // 添加token
        if (withToken) {
            options.header['like-token'] = options.header.token || token
        }
        // 添加终端类型
        options.header['terminal'] = client
        delete options.header.token
        return options
    },
    async responseInterceptorsHook(response, config) {
        try {
        const { isTransformResponse, isReturnDefaultResponse, isAuth } = config

        //返回默认响应，当需要获取响应头及其他数据时可使用
        if (isReturnDefaultResponse) {
            return response
        }
        // 是否需要对数据进行处理
        if (!isTransformResponse) {
            return response.data
        }
            
            // APP 平台下，检查响应数据
            // #ifdef APP-PLUS
            if (!response || !response.data) {
                console.error('APP 平台响应数据异常:', { response, config })
                throw new Error('接口响应数据格式异常')
            }
            // #endif
            
        const { logout } = useUserStore()
            const responseData = response.data as any
            
            // 检查响应数据结构
            if (!responseData || typeof responseData !== 'object') {
                console.error('响应数据格式异常:', { responseData, response })
                throw new Error('接口响应数据格式异常')
            }
            
            const { code, data, msg, show } = responseData
            
            // APP 平台下，记录商品详情接口的响应
            // #ifdef APP-PLUS
            const requestUrl = (response as any).url || (config as any).url || ''
            if (requestUrl.includes('goods/detail') || requestUrl.includes('goodsDetail')) {
                console.log('APP 商品详情接口响应:', {
                    code,
                    data,
                    msg,
                    requestUrl,
                    responseDataExists: !!responseData,
                    dataIsNull: data === null,
                    dataIsUndefined: data === undefined
                })
            }
            // #endif
            
        switch (code) {
            case RequestCodeEnum.SUCCESS:
                return data
            case RequestCodeEnum.PARAMS_TYPE_ERROR:
            case RequestCodeEnum.PARAMS_VALID_ERROR:
            case RequestCodeEnum.REQUEST_METHOD_ERROR:
            case RequestCodeEnum.ASSERT_ARGUMENT_ERROR:
            case RequestCodeEnum.ASSERT_MYBATIS_ERROR:
            case RequestCodeEnum.LOGIN_ACCOUNT_ERROR:
            case RequestCodeEnum.LOGIN_DISABLE_ERROR:
            case RequestCodeEnum.NO_PERMISSTION:
            case RequestCodeEnum.FAILED:
            case RequestCodeEnum.SYSTEM_ERROR:
            case RequestCodeEnum.REQUEST_404_ERROR:
                    // 确保 errorMsg 不为 null 或 undefined
                    const errorMsg = (msg && typeof msg === 'string' && msg.trim()) || '请求失败'
                    
                    // APP 平台下，记录商品详情接口的错误信息
                    // #ifdef APP-PLUS
                    const requestUrl = (response as any).url || (config as any).url || ''
                    if (requestUrl.includes('goods/detail') || requestUrl.includes('goodsDetail')) {
                        console.error('APP 商品详情接口错误:', {
                            code,
                            msg,
                            errorMsg,
                            requestUrl,
                            data: data
                        })
                    }
                    // #endif
                    
                    uni.$u.toast(errorMsg)
                    return Promise.reject(new Error(errorMsg))

            case RequestCodeEnum.TOKEN_INVALID:
            case RequestCodeEnum.TOKEN_EMPTY:
                logout()
                if (isAuth && !getToken()) {
                    router.navigateTo('/pages/login/login')
                }
                    return Promise.reject(new Error(msg || '登录已过期，请重新登录'))
            case RequestCodeEnum.PAYMENT_ERROR:
                    const paymentMsg = msg || '支付失败'
                    uni.$u.toast(paymentMsg)
                    return Promise.reject(new Error(paymentMsg))
            case RequestCodeEnum.BIND_RELATION_ERROR:
                    return Promise.reject(new Error(msg || '绑定关系错误'))
            default:
                    // 如果 code 未定义，可能是响应格式问题
                    if (code === undefined || code === null) {
                        console.error('响应码未定义:', { responseData, response })
                        throw new Error('接口响应格式异常')
                    }
                return data
            }
        } catch (hookError: any) {
            console.error('响应拦截器处理失败:', {
                hookError,
                errorType: typeof hookError,
                errorIsNull: hookError === null,
                errorIsUndefined: hookError === undefined,
                response,
                config
            })
            // 确保总是 reject 一个有意义的错误
            const errorMessage = hookError?.message || 
                                hookError?.msg || 
                                (hookError && typeof hookError === 'string' ? hookError : String(hookError)) || 
                                '接口处理失败'
            return Promise.reject(new Error(errorMessage))
        }
    },
    async responseInterceptorsCatchHook(options, error) {
        // APP 平台下，记录详细的错误信息
        // #ifdef APP-PLUS
        console.error('APP 平台响应拦截器捕获错误:', {
            error,
            errorType: typeof error,
            errorIsNull: error === null,
            errorIsUndefined: error === undefined,
            errorMsg: error?.errMsg || error?.message,
            url: options.url,
            method: options.method
        })
        // #endif
        
        if (options.method?.toUpperCase() == RequestMethodsEnum.POST) {
            uni.$u.toast('请求失败，请重试')
        }
        
        // 确保返回的不是 null
        // #ifdef APP-PLUS
        if (error === null || error === undefined) {
            return Promise.reject(new Error('请求失败，请检查网络连接'))
        }
        // #endif
        
        return Promise.reject(error)
    }
}

const defaultOptions: HttpRequestOptions = {
    requestOptions: {
        timeout: 10 * 1000
    },
    baseUrl: `${import.meta.env.VITE_APP_BASE_URL || ''}/`,
    //是否返回默认的响应
    isReturnDefaultResponse: false,
    // 需要对返回数据进行处理
    isTransformResponse: true,
    // 接口拼接地址
    urlPrefix: 'api',
    // 忽略重复请求
    ignoreCancel: false,
    // 是否携带token
    withToken: true,
    isAuth: false,
    retryCount: 2,
    retryTimeout: 1000,
    requestHooks: requestHooks
}

function createRequest(opt?: HttpRequestOptions) {
    return new HttpRequest(
        // 深度合并
        merge(defaultOptions, opt || {})
    )
}
const request = createRequest()
export default request
